#include <QtGui>
#include "dirutils.h"
#include "urlutils.h"
#include "playlistlistmodel.h"

bool baseNameLessThan(const QFileInfo& l, const QFileInfo& r) {
    return UrlUtils::baseName(l).toLower() < UrlUtils::baseName(r).toLower();
}

int PlayListListModel::indexOf(QString path) const {
    for (int i=0; i<rowCount(); ++i) {
        if (data(index(i,0), PathRole).toString() == path) return i;
    }
    return -1;
}

PlayListListModel::PlayListListModel(QObject *parent) :
    QAbstractListModel(parent)
{
    QHash<int, QByteArray> roles;
    roles[NameRole] = "name";
    roles[PathRole] = "path";
    setRoleNames(roles);
    QSettings s;
    if (s.value("playedsomething").toBool() || s.value("cleanexit").toBool())
        restoreFromSettings();

}

void PlayListListModel::addSongDirectory(QString path) {
    QSettings s;
    QFileInfo finfo(path);
    Q_ASSERT(finfo.isDir());
    QStringList songdirs = s.value("songdirs", QStringList()).toStringList();
    if (!songdirs.contains(path)) {
        songdirs << path;
        s.setValue("songdirs", songdirs);
    }
    scanForSongDirs(path);
}

void PlayListListModel::restoreFromSettings() {
    clear();

    QSettings s;
    QStringList m3udirs = s.value("m3udirs", QStringList()).toStringList();
    QStringList songDirs = s.value("songdirs", QStringList()).toStringList();
    QString podcastDir = s.value("podcastdir", QString()).toString();
    QString show = s.value("show", tr("All")).toString();
    if ((show == tr("All")) || (show == tr("Playlists")))
        foreach (QString m3udir, m3udirs) {
            scanForPlaylists(m3udir);
        }
    if ((!podcastDir.isEmpty()) && ((show == tr("All")) || (show == tr("Podcasts"))))
        scanForSongDirs(podcastDir);

    if ((show == tr("All")) || (show == tr("Song Folders")))
        foreach (QString songDir, songDirs) {
            scanForSongDirs(songDir);
        }
    reset();
}

void PlayListListModel::scanForSongDirs(QString dir) {
    QSettings s;
    QList<QFileInfo> newInfos;
    // QString podcastDir = s.value("podcastdir", QString()).toString()
    QStringList removedRows = s.value("removedList", QStringList()).toStringList();
    foreach (QString songDir, DirUtils::songFoldersInDir(dir)) {
        if (removedRows.contains(songDir)) continue;
        newInfos << QFileInfo(songDir);
    }
    newInfos << dir;
    if (newInfos.count() > 0) {
        int start = rowCount();
        int end = start + newInfos.count() - 1;
        beginInsertRows(QModelIndex(), start, end);
        m_playlists << newInfos;
        endInsertRows();
    }
}

int PlayListListModel::rowCount(const QModelIndex &parent) const {
    if (parent == QModelIndex()) 
        return m_playlists.count();
    else return 0;
}

QVariant PlayListListModel::data(const QModelIndex &index, int role) const {
    if (!index.isValid()) return QVariant();
    int r = index.row();
    if (r >= m_playlists.count()) return QVariant();
    if (role == Qt::DecorationRole) {
        if (m_playlists[r].isDir())
            return qApp->style()->standardIcon(QStyle::SP_DirIcon);
        else return qApp->style()->standardIcon(QStyle::SP_FileIcon);
    }
    if ((role == Qt::DisplayRole) || (role == NameRole)) {
        return UrlUtils::baseName(m_playlists[r]);
    }
    else if ( (role == Qt::ToolTipRole) ||
         (role == Qt::EditRole) | (role == PathRole)) {
         return m_playlists[r].absoluteFilePath();
    }

    return QVariant();
}


void PlayListListModel::clear() {
    if (m_playlists.count() > 0) {
        m_playlists.clear();
    }
    reset();
}

void PlayListListModel::closePlaylist(QString path) {
    int idx = -1;
    for (int i=0; i<m_playlists.count(); ++i) {
        if (m_playlists[i].absoluteFilePath() == path) {
            idx = i;
            break;
        }
    }
    if (idx != -1) {
        removeRows(idx, 1, QModelIndex());
    }

}

bool PlayListListModel::removeRows(int row, int count, const QModelIndex &) {
    QStringList sl;
    emit beginRemoveRows(QModelIndex(), row, row + count - 1);
    for (int c=0; c<count; ++c) {
        QFileInfo fi = m_playlists.at(row);
        m_playlists.removeAt(row);
        sl << fi.absoluteFilePath();
    }
    emit endRemoveRows();
    QSettings s;
    QStringList removedRows = s.value("removedList", QStringList()).toStringList();
    removedRows << sl;
    s.setValue("removedList", removedRows);
    return true;
}


void PlayListListModel::addM3uDirectory(QString path) {
    QSettings s;
    QStringList m3udirs = s.value("m3udirs", QStringList()).toStringList();
    if (!m3udirs.contains(path)) {
        m3udirs << path;
        s.setValue("m3udirs", m3udirs);
    }
    scanForPlaylists(path);

}

void PlayListListModel::scanForPlaylists(QString path) {
    QSettings s;
    QStringList removedRows = s.value("removedList", QStringList()).toStringList();
    QFileInfo fi(path);
    if (!fi.isDir()) path = fi.absolutePath();

    QDirIterator itr(path,  QStringList() << "*.m3u",
                     QDir::NoSymLinks | QDir::Files,
                     QDirIterator::Subdirectories);

    QList<QFileInfo> finfolist;
    while (itr.hasNext()) {
        QString str = itr.next();
        if (removedRows.contains(str)) continue;
        finfolist << QFileInfo (str);
    }
    qSort(finfolist.begin(), finfolist.end(), baseNameLessThan);
    int start = rowCount();
    int end = start + finfolist.count() - 1;
    beginInsertRows(QModelIndex(), start, end);
    m_playlists << finfolist;
    endInsertRows();
}
